added new scanner token "unbind" which gets rid of a key binding (in fact,
authorMichael Natterer <mitch@imendio.com>
Thu, 5 Oct 2006 14:48:57 +0000 (14:48 +0000)
committerMichael Natterer <mitch@src.gnome.org>
Thu, 5 Oct 2006 14:48:57 +0000 (14:48 +0000)
2006-10-05  Michael Natterer  <mitch@imendio.com>

* gtk/gtkrc.[ch]: added new scanner token "unbind" which gets
rid of a key binding (in fact, it only lets it appear unbound).

* gtk/gtkbindings.[ch] (struct GtkBindingEntry): added
"guint marks_unbound : 1"

(gtk_binding_entry_skip): new API which marks the entry as unbound.

Changed code so it returns FALSE when "marks_unbound == TRUE" is
encountered while activating bindings, effectively letting the
binding appear unbound (regardless of still existing bindings in
lower binding priority levels). Fixes bug #358329.

(gtk_binding_entry_add)
(gtk_binding_entry_clear)
(gtk_binding_entry_add_signall)
(gtk_binding_parse_binding): deprected these functions.

(_gtk_binding_parse_binding)
(_gtk_binding_entry_add_signall): new internal API.

* gtk/gtk.symbols: changed accordingly.

ChangeLog
gtk/gtk.symbols
gtk/gtkbindings.c
gtk/gtkbindings.h
gtk/gtkrc.c
gtk/gtkrc.h

index 0976552875ad9064b04033a025febab7686f7a7f..9f958bb1f6fc2541f7e3fdc8b000e9b5187d10a0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2006-10-05  Michael Natterer  <mitch@imendio.com>
+
+       * gtk/gtkrc.[ch]: added new scanner token "unbind" which gets
+       rid of a key binding (in fact, it only lets it appear unbound).
+
+       * gtk/gtkbindings.[ch] (struct GtkBindingEntry): added
+       "guint marks_unbound : 1"
+
+       (gtk_binding_entry_skip): new API which marks the entry as unbound.
+
+       Changed code so it returns FALSE when "marks_unbound == TRUE" is
+       encountered while activating bindings, effectively letting the
+       binding appear unbound (regardless of still existing bindings in
+       lower binding priority levels). Fixes bug #358329.
+
+       (gtk_binding_entry_add)
+       (gtk_binding_entry_clear)
+       (gtk_binding_entry_add_signall)
+       (gtk_binding_parse_binding): deprected these functions.
+
+       (_gtk_binding_parse_binding)
+       (_gtk_binding_entry_add_signall): new internal API.
+
+       * gtk/gtk.symbols: changed accordingly.
+
 2006-10-03  Matthias Clasen  <mclasen@redhat.com>
 
        Fix interaction of GtkEntryCompletion with input
index 001ef33110ecd8eea375390d8ce32f119689762a..da17fe5e98c407002e332fd837b235fa4bd6f121 100644 (file)
@@ -372,11 +372,14 @@ gtk_aspect_frame_set
 
 #if IN_HEADER(__GTK_BINDINGS_H__)
 #if IN_FILE(__GTK_BINDINGS_C__)
-gtk_binding_entry_add_signal
-gtk_binding_entry_add_signall
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_binding_entry_clear
-gtk_binding_entry_remove
+gtk_binding_entry_add_signall
 gtk_binding_parse_binding
+#endif
+gtk_binding_entry_skip
+gtk_binding_entry_add_signal
+gtk_binding_entry_remove
 gtk_bindings_activate
 gtk_bindings_activate_event
 gtk_binding_set_activate
index fcba628870bb15d3075b694a19f563529577e74f..2d2786a96034353e4560977635f9d18658976eea 100644 (file)
@@ -206,6 +206,7 @@ binding_entry_new (GtkBindingSet  *binding_set,
   entry->binding_set = binding_set,
   entry->destroyed = FALSE;
   entry->in_emission = FALSE;
+  entry->marks_unbound = FALSE;
   entry->signals = NULL;
 
   entry->set_next = binding_set->entries;
@@ -568,7 +569,7 @@ gtk_binding_set_new (const gchar    *set_name)
   g_return_val_if_fail (set_name != NULL, NULL);
   
   binding_set = g_new (GtkBindingSet, 1);
-  binding_set->set_name = g_intern_string (set_name);
+  binding_set->set_name = (gchar *) g_intern_string (set_name);
   binding_set->widget_path_pspecs = NULL;
   binding_set->widget_class_pspecs = NULL;
   binding_set->class_branch_pspecs = NULL;
@@ -665,6 +666,26 @@ gtk_binding_entry_clear (GtkBindingSet     *binding_set,
   entry = binding_entry_new (binding_set, keyval, modifiers);
 }
 
+void
+gtk_binding_entry_skip (GtkBindingSet  *binding_set,
+                        guint           keyval,
+                        GdkModifierType modifiers)
+{
+  GtkBindingEntry *entry;
+
+  g_return_if_fail (binding_set != NULL);
+
+  keyval = gdk_keyval_to_lower (keyval);
+  modifiers = modifiers & BINDING_MOD_MASK ();
+
+  entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
+  if (entry)
+    binding_entry_destroy (entry);
+
+  entry = binding_entry_new (binding_set, keyval, modifiers);
+  entry->marks_unbound = TRUE;
+}
+
 void
 gtk_binding_entry_remove (GtkBindingSet         *binding_set,
                          guint           keyval,
@@ -684,10 +705,22 @@ gtk_binding_entry_remove (GtkBindingSet    *binding_set,
 
 void
 gtk_binding_entry_add_signall (GtkBindingSet  *binding_set,
-                              guint           keyval,
-                              GdkModifierType modifiers,
-                              const gchar    *signal_name,
-                              GSList         *binding_args)
+                               guint          keyval,
+                               GdkModifierType modifiers,
+                               const gchar    *signal_name,
+                               GSList        *binding_args)
+{
+  _gtk_binding_entry_add_signall (binding_set,
+                                  keyval, modifiers,
+                                  signal_name, binding_args);
+}
+
+void
+_gtk_binding_entry_add_signall (GtkBindingSet  *binding_set,
+                                guint         keyval,
+                                GdkModifierType modifiers,
+                                const gchar    *signal_name,
+                                GSList       *binding_args)
 {
   GtkBindingEntry *entry;
   GtkBindingSignal *signal, **signal_p;
@@ -929,10 +962,13 @@ binding_match_activate (GSList          *pspec_list,
                        GtkObject       *object,
                        guint            path_length,
                        gchar           *path,
-                       gchar           *path_reversed)
+                       gchar           *path_reversed,
+                        gboolean        *unbound)
 {
   GSList *slist;
 
+  *unbound = FALSE;
+
   for (slist = pspec_list; slist; slist = slist->next)
     {
       PatternSpec *pspec;
@@ -952,8 +988,17 @@ binding_match_activate (GSList          *pspec_list,
            binding_set = pspec->user_data;
         }
 
-      if (binding_set && gtk_binding_entry_activate (binding_set->current, object))
-        return TRUE;
+      if (binding_set)
+        {
+          if (binding_set->current->marks_unbound)
+            {
+              *unbound = TRUE;
+              return FALSE;
+            }
+
+          if (gtk_binding_entry_activate (binding_set->current, object))
+            return TRUE;
+        }
     }
 
   return FALSE;
@@ -1047,13 +1092,17 @@ gtk_bindings_activate_list (GtkObject *object,
       guint path_length;
       gchar *path, *path_reversed;
       GSList *patterns;
+      gboolean unbound;
 
       gtk_widget_path (widget, &path_length, &path, &path_reversed);
       patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET, is_release);
-      handled = binding_match_activate (patterns, object, path_length, path, path_reversed);
+      handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
       g_slist_free (patterns);
       g_free (path);
       g_free (path_reversed);
+
+      if (unbound)
+        return FALSE;
     }
 
   if (!handled)
@@ -1061,20 +1110,25 @@ gtk_bindings_activate_list (GtkObject *object,
       guint path_length;
       gchar *path, *path_reversed;
       GSList *patterns;
+      gboolean unbound;
 
       gtk_widget_class_path (widget, &path_length, &path, &path_reversed);
       patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_WIDGET_CLASS, is_release);
-      handled = binding_match_activate (patterns, object, path_length, path, path_reversed);
+      handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
       g_slist_free (patterns);
       g_free (path);
       g_free (path_reversed);
+
+      if (unbound)
+        return FALSE;
     }
 
   if (!handled)
     {
       GSList *patterns;
       GType class_type;
-      
+      gboolean unbound = FALSE;
+
       patterns = gtk_binding_entries_sort_patterns (entries, GTK_PATH_CLASS, is_release);
       class_type = G_TYPE_FROM_INSTANCE (object);
       while (class_type && !handled)
@@ -1082,18 +1136,24 @@ gtk_bindings_activate_list (GtkObject *object,
          guint path_length;
          gchar *path;
          gchar *path_reversed;
-         
+
          path = g_strdup (g_type_name (class_type));
          path_reversed = g_strdup (path);
          g_strreverse (path_reversed);
          path_length = strlen (path);
-         handled = binding_match_activate (patterns, object, path_length, path, path_reversed);
+         handled = binding_match_activate (patterns, object, path_length, path, path_reversed, &unbound);
          g_free (path);
          g_free (path_reversed);
 
+          if (unbound)
+            break;
+
          class_type = g_type_parent (class_type);
        }
       g_slist_free (patterns);
+
+      if (unbound)
+        return FALSE;
     }
 
   return handled;
@@ -1335,12 +1395,15 @@ gtk_binding_parse_bind (GScanner       *scanner,
 {
   guint keyval = 0;
   GdkModifierType modifiers = 0;
+  gboolean unbind = FALSE;
 
   g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
   
   g_scanner_get_next_token (scanner);
-  if (scanner->token != GTK_RC_TOKEN_BIND)
+  if (scanner->token != GTK_RC_TOKEN_BIND &&
+      scanner->token != GTK_RC_TOKEN_UNBIND)
     return GTK_RC_TOKEN_BIND;
+  unbind = scanner->token == GTK_RC_TOKEN_UNBIND;
   g_scanner_get_next_token (scanner);
   if (scanner->token != G_TOKEN_STRING)
     return G_TOKEN_STRING;
@@ -1349,7 +1412,14 @@ gtk_binding_parse_bind (GScanner       *scanner,
   if (keyval == 0)
     return G_TOKEN_STRING;
 
+  if (unbind)
+    {
+      gtk_binding_entry_skip (binding_set, keyval, modifiers);
+      return G_TOKEN_NONE;
+    }
+
   g_scanner_get_next_token (scanner);
+
   if (scanner->token != '{')
     return '{';
 
@@ -1382,7 +1452,13 @@ gtk_binding_parse_bind (GScanner       *scanner,
 }
 
 guint
-gtk_binding_parse_binding (GScanner       *scanner)
+gtk_binding_parse_binding (GScanner *scanner)
+{
+  return _gtk_binding_parse_binding (scanner);
+}
+
+guint
+_gtk_binding_parse_binding (GScanner *scanner)
 {
   gchar *name;
   GtkBindingSet *binding_set;
@@ -1420,6 +1496,7 @@ gtk_binding_parse_binding (GScanner       *scanner)
          guint expected_token;
 
        case GTK_RC_TOKEN_BIND:
+       case GTK_RC_TOKEN_UNBIND:
          expected_token = gtk_binding_parse_bind (scanner, binding_set);
          if (expected_token != G_TOKEN_NONE)
            return expected_token;
index 7e28d8459d95f639e1f84bc40ecf237449f55f07..a3109b2988b710f46c540ca74361fc6a8b819bfd 100644 (file)
@@ -69,6 +69,7 @@ struct _GtkBindingEntry
   GtkBindingSet                *binding_set;
   guint                        destroyed : 1;
   guint                        in_emission : 1;
+  guint                 marks_unbound : 1;
   GtkBindingEntry      *set_next;
   GtkBindingEntry      *hash_next;
   GtkBindingSignal     *signals;
@@ -106,16 +107,33 @@ gboolean gtk_binding_set_activate (GtkBindingSet  *binding_set,
                                         guint           keyval,
                                         GdkModifierType modifiers,
                                         GtkObject      *object);
+
+#ifndef GTK_DISABLE_DEPRECATED
 #define         gtk_binding_entry_add          gtk_binding_entry_clear
 void    gtk_binding_entry_clear        (GtkBindingSet  *binding_set,
                                         guint           keyval,
                                         GdkModifierType modifiers);
-void    gtk_binding_entry_add_signal   (GtkBindingSet  *binding_set,
+void    gtk_binding_entry_add_signall  (GtkBindingSet  *binding_set,
                                         guint           keyval,
                                         GdkModifierType modifiers,
                                         const gchar    *signal_name,
-                                        guint           n_args,
-                                        ...);
+                                        GSList         *binding_args);
+guint   gtk_binding_parse_binding      (GScanner       *scanner);
+#endif /* GTK_DISABLE_DEPRECATED */
+
+void    gtk_binding_entry_skip         (GtkBindingSet  *binding_set,
+                                         guint           keyval,
+                                         GdkModifierType modifiers);
+void    gtk_binding_entry_add_signal   (GtkBindingSet  *binding_set,
+                                         guint           keyval,
+                                         GdkModifierType modifiers,
+                                         const gchar    *signal_name,
+                                         guint           n_args,
+                                         ...);
+void    gtk_binding_entry_remove       (GtkBindingSet  *binding_set,
+                                        guint           keyval,
+                                        GdkModifierType modifiers);
+
 void    gtk_binding_set_add_path       (GtkBindingSet  *binding_set,
                                         GtkPathType     path_type,
                                         const gchar    *path_pattern,
@@ -124,18 +142,13 @@ void       gtk_binding_set_add_path       (GtkBindingSet  *binding_set,
 
 /* Non-public methods */
 
-void    gtk_binding_entry_remove       (GtkBindingSet  *binding_set,
-                                        guint           keyval,
-                                        GdkModifierType modifiers);
-void    gtk_binding_entry_add_signall  (GtkBindingSet  *binding_set,
+guint   _gtk_binding_parse_binding     (GScanner       *scanner);
+void     _gtk_binding_reset_parsed      (void);
+void    _gtk_binding_entry_add_signall (GtkBindingSet  *binding_set,
                                         guint           keyval,
                                         GdkModifierType modifiers,
                                         const gchar    *signal_name,
                                         GSList         *binding_args);
-guint   gtk_binding_parse_binding      (GScanner       *scanner);
-
-
-void     _gtk_binding_reset_parsed    (void);
 
 /* Creates a signal with a fixed callback instead of a class offset;
  * useful for key binding signals
index a570d62f3114c3abbf481c773115f35351bcd395..c5bc23cf1449661a849c9d0b51cd006e400da050 100644 (file)
@@ -319,7 +319,8 @@ static const gchar symbol_names[] =
   "im_module_file\0"
   "LTR\0"
   "RTL\0"
-  "color\0";
+  "color\0"
+  "unbind\0";
 
 static const struct
 {
@@ -361,7 +362,8 @@ static const struct
   { 245, GTK_RC_TOKEN_IM_MODULE_FILE },
   { 260, GTK_RC_TOKEN_LTR },
   { 264, GTK_RC_TOKEN_RTL },
-  { 268, GTK_RC_TOKEN_COLOR }
+  { 268, GTK_RC_TOKEN_COLOR },
+  { 274, GTK_RC_TOKEN_UNBIND }
 };
 
 static GHashTable *realized_style_ht = NULL;
@@ -2858,7 +2860,7 @@ gtk_rc_parse_statement (GtkRcContext *context,
       return gtk_rc_parse_style (context, scanner);
       
     case GTK_RC_TOKEN_BINDING:
-      return gtk_binding_parse_binding (scanner);
+      return _gtk_binding_parse_binding (scanner);
       
     case GTK_RC_TOKEN_PIXMAP_PATH:
       return gtk_rc_parse_pixmap_path (context, scanner);
index 2fd8f3e4401d6a9fa9a72ee39091374f6580868d..d107df19365ef73b85d68d349e23dcceedbb2699 100644 (file)
@@ -217,6 +217,7 @@ typedef enum {
   GTK_RC_TOKEN_LTR,
   GTK_RC_TOKEN_RTL,
   GTK_RC_TOKEN_COLOR,
+  GTK_RC_TOKEN_UNBIND,
   GTK_RC_TOKEN_LAST
 } GtkRcTokenType;